package com.xian.im.modules.avchat.manager;

import com.alibaba.cloud.commons.lang.StringUtils;
import com.alibaba.nacos.common.utils.MD5Utils;
import com.xian.feign.GroupChannelClient;
import com.xian.im.common.constant.CommandCodeConstant;
import com.xian.im.common.constant.CommandConstant;
import com.xian.im.common.enums.UniqueTypeGenerateEnums;
import com.xian.im.common.proto.MsgResponse;
import com.xian.im.common.sequence.UniqueSnowFlakeGenerate;
import com.xian.im.common.thread.CallbackWhenException;
import com.xian.im.common.thread.DynamicThreadPool;
import com.xian.im.common.thread.RunnableWithExceptionProtection;
import com.xian.im.common.utils.sys.SpringContextHolder;
import com.xian.im.modules.im.core.IGroupUserCoreService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.security.NoSuchAlgorithmException;
import java.util.Set;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @program: xian-im-server
 * @description:  群组管理
 * @author: liru.xian
 * @create: 2021-01-28 20:43
 **/
@Slf4j
@Component
public class ImGroupManager extends AbsManager {
    private static ThreadPoolExecutor threadPool = DynamicThreadPool.getDynamicThreadPool().getThreadPool();

    public static final String GROUP_RECORD = "group:record:";
    private final IGroupUserCoreService groupUserCoreService;
    private final RedisTemplate redisTemplate;

    public ImGroupManager(IGroupUserCoreService groupUserCoreService, RedisTemplate redisTemplate) {
        this.groupUserCoreService = groupUserCoreService;
        this.redisTemplate = redisTemplate;
    }

    /**
     * 是否是管理员
     * @param account
     * @param groupId
     * @return
     */
    public Boolean isManager(String account,String groupId){
        return groupUserCoreService.exist(account,groupId);
    }
    /**
     *  添加管理员
     * @param account
     * @param groupId
     * @return
     */
    public  Boolean addManager(String account,String groupId){
        return groupUserCoreService.addManager(account,groupId);
    }
    /**
     *  删除管理员
     * @param account
     * @param groupId
     * @return
     */
    public Boolean removeManager(String account,String groupId){
        return groupUserCoreService.removeManager(account,groupId);
    }
    /**
     *  获取群组所有管理员信息
     * @param groupId
     * @return
     */
    public Set<String> getManagers(String groupId){
        return groupUserCoreService.getUserAccountByGroupId(groupId);
    }

    /**
     *
     * @param body
     * @param groupId
     * @return
     */
    public Boolean sendMessage(String body,String groupId){
        MsgResponse response = MsgResponse.buildSuccess();
        response.setCmd(CommandConstant.SYSTEM_CMD);
        response.setCmdCode(CommandCodeConstant.SYSTEM_GROUP);
        UniqueSnowFlakeGenerate uniqueSnowFlakeGenerate = SpringContextHolder.getBean(UniqueSnowFlakeGenerate.class);
        String uniqueId = StringUtils.isBlank(response.getUniqueId()) ? uniqueSnowFlakeGenerate.getSerialId(UniqueTypeGenerateEnums.xim_MSG.getCode()) : response.getUniqueId();
        response.setUniqueId(uniqueId);
        response.setBody(body);
        threadPool.execute(new RunnableWithExceptionProtection<>(new Runnable() {
            @Override
            public void run() {
                GroupChannelClient channelClient = SpringContextHolder.getBean(GroupChannelClient.class);
                channelClient.pushGroupMessage(groupId,response);
            }
        }, new CallbackWhenException() {
            @Override
            public void handle(Throwable t, Object data) {
                log.warn("发送错误 发送信息{} ,错误提示{}",data,t.getMessage());
            }
        },response));
        return Boolean.TRUE;
    }

    /**
     *  记录在线
     * @param groupId
     * @param ctxId
     */
    public void recordOnLine(String groupId,String ctxId) throws NoSuchAlgorithmException {
        ctxId = MD5Utils.md5Hex(ctxId.getBytes());
        redisTemplate.opsForValue().set(GROUP_RECORD+ctxId+":"+groupId,System.currentTimeMillis(),12, TimeUnit.HOURS);
    }

    /**
     *  下线记录
     * @param groupId
     * @param ctxId
     */
    public void recordOffline(String groupId,String ctxId){
        try {
            ctxId =MD5Utils.md5Hex(ctxId.getBytes());
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        redisTemplate.delete(GROUP_RECORD+ctxId+":"+groupId);
    }

    /**
     *  下线记录
     * @param ctxId
     */
    public void recordOffline(String ctxId){
        try {
            ctxId =MD5Utils.md5Hex(ctxId.getBytes());
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        Set<String> keys = keys(GROUP_RECORD + ctxId+"*");
        redisTemplate.delete(keys);
        for (String key : keys) {
            String[] split = key.split(":");
            if(split.length == 0){
                return;
            }
            String group = split[split.length-1];
        }
    }

    /**
     *
     * @param groupId
     * @param ctxId
     */
    public Boolean isOnline(String groupId,String ctxId){
        try {
            ctxId =MD5Utils.md5Hex(ctxId.getBytes());
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        Object o = redisTemplate.opsForValue().get(GROUP_RECORD + ctxId + ":" + groupId);
        return o != null;
    }


}
